﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xant.Querier.Core;

namespace Xant.Querier.Compilers
{
    /// <summary>
    /// 专用于Microsoft SQL Server数据库平台的脚本编译器
    /// </summary>
    public class MsSqlScriptCompiler : SqlWhereClauseCompiler
    {
        public MsSqlScriptCompiler(Query query):base(query)
        {
        }

        protected override string PerformCompile()
        {
            if (Query.Pagination == null || Query.Pagination.PageSize <= 0)//如非指定分页
            {
                return base.PerformCompile();
            }
            var gsp = base.GenSelectPart;
            base.GenSelectPart = false; //如果指定了分页，那么生成的脚本先不包含SELECT部分
            var whereClause = base.PerformCompile();
            string orderBy = null;
            var config = EntityConfigurationManager.FindEntityConfiguration(this.Query.SourceEntityType.Name);
            if (Query.OrderClause != null)
            {
                orderBy = base.CompileOrderBy();
            }
            else
            {
                var propertyId = Query.SourceEntityType.GetProperties().Where(p => p.Name.EndsWith("Id", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                if (propertyId == null)
                    propertyId = Query.SourceEntityType.GetProperties().First();
                orderBy = string.Format("ORDER BY {0}.{1} ASC", config.TableAlias, propertyId.Name);
            }
            var sqlRowNumber = string.Format(" [row_number]=ROW_NUMBER() OVER ({0}) ", orderBy);
            var format = config.TableName.Equals(config.TableAlias, StringComparison.InvariantCultureIgnoreCase)
                ? "SELECT *, {0} FROM {1}"
                : "SELECT *, {0} FROM {1} AS {2}";
            var select = string.Format(format, sqlRowNumber, config.TableName, config.TableAlias);
            if (!string.IsNullOrEmpty(whereClause))
            {
                select = select + " WHERE " + whereClause;
            }
            var sqlPage = string.Format("SELECT * FROM(\n{0}\n) AS T WHERE T.[row_number] BETWEEN {1} AND {2};", select, Query.Pagination.PageSize * Query.Pagination.PageIndex + 1, Query.Pagination.PageSize * (Query.Pagination.PageIndex + 1));
            return sqlPage;
        }

    }

}
